package com.ac.api.process_task.controller;

import com.ac.api.equipment.entity.Equipment;
import com.ac.api.equipment.service.EquipmentService;
import com.ac.api.process_line.entity.LineVo;
import com.ac.api.process_line.entity.ProcessLine;
import com.ac.api.process_line.entity.TaskVo;
import com.ac.api.process_line.service.ProcessLineService;
import com.ac.utils.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.web.bind.annotation.RequestMapping;
import com.base.annotation.SysLog;
import org.springframework.web.bind.annotation.RestController;
import com.base.helper.BaseController;
import com.base.helper.Result;
import com.ac.api.process_task.entity.ProcessTask;
import com.ac.api.process_task.service.ProcessTaskService;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 工序任务单表 前端控制器
 * </p>
 *
 * @author dc
 * @since 2025-06-11
 */
@Api(tags = "ProcessTask（工序区）")
@RestController
@RequestMapping("/processTask")
public class ProcessTaskController extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(ProcessTaskController.class);
    @Autowired
    private ProcessTaskService entityService;
    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private ProcessLineService processLineService;

    @SysLog(action = "findByPage", value = "分页查询工序区")
    @ApiOperation(value = "分页查询工序区", notes = "分页查询工序区")
    @GetMapping("/findByPage")
    @ApiImplicitParams({ @ApiImplicitParam(name = "size", value = "分页大小", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面：从1开始", paramType = "query") })
    public Result<IPage<ProcessTask>> findByPage(final ProcessTask example, final Page page) {
        IPage<ProcessTask> records = entityService.page(example, page);
        return new Result(true, records);
    }

    @SysLog(action = "delete", value = "删除工序区")
    @ApiOperation(value = "删除工序区")
    @DeleteMapping(value = "/delete/{id}")
    @ApiImplicitParam(name = "id", value = "工序区ID", required = true, paramType = "path")
    public Result delete(@PathVariable final Integer id) {
        try {
            entityService.removeById(id);
            List<Equipment> equipmentList =equipmentService.list(new QueryWrapper<Equipment>().eq("production_task_id",id));
            for (Equipment equip : equipmentList){
                equipmentService.updateById(equip
                        .setProductionTaskId(0)
                        .setUpdatedAt(LocalDateTime.now())
                        .setStatus("停机")//将设备移除
                );
            }
            return new Result(true, "成功删除工序区", null);
        } catch (DataIntegrityViolationException e) {
            LOG.error("删除工序区失败", e);
            return new Result(false, "删除工序区失败", "该工序区不能删除，存在其他关联数据");
        } catch (Exception e) {
            LOG.error("删除工序区失败", e);
            return new Result(false, "删除工序区失败", e.getMessage());
        }
    }

    @SysLog(action = "one", value = "查询单个工序区")
    @ApiOperation(value = "查询单个工序区")
    @GetMapping(value = "/one/{id}")
    @ApiImplicitParam(name = "id", value = "工序区ID", required = true, paramType = "path")
    public Result one(@PathVariable final Integer id) {
        try {
            ProcessTask entity = entityService.getById(id);
            return new Result(true, entity);
        } catch (Exception e) {
            LOG.error("查询单个工序区失败", e);
            return new Result(false, new ProcessTask());
        }
    }

    @SysLog(action = "add", value = "添加工序区")
    @ApiOperation(value = "添加工序区")
    @PostMapping("/add")
    public Result add(@Valid @RequestBody final ProcessTask entity, final BindingResult result) {
        try {
            if (result.hasErrors()) {
                Map<String, String> map = this.getErrors(result);
                String errorMsg = map.entrySet().iterator().next().getValue();
                return new Result(false, "保存工序区失败", errorMsg, map);
            } else {
                entityService.save(entity);
                return new Result(true, "成功保存工序区", null);
            }
        } catch (Exception e) {
            LOG.error("添加工序区失败", e);
            return new Result(false, "保存工序区失败", e.getMessage());
        }
    }

    @SysLog(action = "update", value = "修改工序区")
    @ApiOperation(value = "修改工序区")
    @PostMapping("/update")
    public Result update(@Valid @RequestBody final ProcessTask entity, final BindingResult result) {
        try {
            if (result.hasErrors()) {
                Map<String, String> map = this.getErrors(result);
                String errorMsg = map.entrySet().iterator().next().getValue();
                return new Result(false, "修改工序区失败", errorMsg, map);
            } else {
                if (null == entity.getTaskId()) {
                    throw new RuntimeException("id不能为空");
                }
                entityService.updateById(entity);
                return new Result(true, "成功修改工序区", null);
            }
        } catch (Exception e) {
            LOG.error("修改工序区失败", e);
            return new Result(false, "修改工序区失败", e.getMessage());
        }
    }

    @SysLog(action = "all", value = "查询全部工序区")
    @ApiOperation(value = "全部工序区")
    @RequestMapping(value = "all", method = RequestMethod.GET)
    public Result<List<ProcessTask>> all(ProcessTask example) {
        List<ProcessTask> entitys = entityService.list(example);
        if (null != entitys) {
            return new Result<>(true, entitys);
        }
        return new Result<>(true, Collections.emptyList());
    }

    // 为工序区添加设备
    @SysLog(action = "addDevice", value = "为工序区添加设备")
    @ApiOperation(value = "为工序区添加设备")
    @RequestMapping(value = "addDevice", method = RequestMethod.POST)
    public Result addDevice(Integer processTaskId, Integer deviceId) {
        Equipment equipment = equipmentService.getById(deviceId);
        if (equipment == null) {
            return new Result(false, "设备不存在");
        }
        equipment.setProductionTaskId(processTaskId);
        equipment.setUpdatedAt(LocalDateTime.now());
        equipment.setStatus("运行");
        equipmentService.updateById(equipment);
        return new Result(true, "成功将设备加入工序区", null);
    }

    // 查看工序区详情
    @SysLog(action = "detail", value = "查看工序区详情")
    @ApiOperation(value = "查看工序区详情")
    @GetMapping("/detail/{id}")
    public Result detail(@PathVariable Integer id) {
        ProcessTask processTask = entityService.getById(id);
        List list = equipmentService.list(new QueryWrapper<Equipment>().eq("production_task_id", id));
        TaskVo taskVo = new TaskVo(processTask.getTaskId(), processTask.getLineId(), processTask.getProcessName(),
                 processTask.getStatus(),
                processTask.getCreatedAt(), processTask.getUpdatedAt(), processTask.getProductModel(), list);
        return new Result<>(true, taskVo);
    }

    //查询设备可用工序区查询设备可用工序区
    @SysLog(action = "availableProcessTask", value = "查询设备可用工序区")
    @ApiOperation(value = "查询设备可用工序区")//设备的type对应task的process_name
    @GetMapping("/availableProcessTask")
    public Result<List<ProcessTask>> availableProcessTask(@RequestParam Integer deviceId) {
        Equipment equipment = equipmentService.getById(deviceId);
        if (equipment == null) {
            return new Result(false, "设备不存在");
        }
        return new Result<>(true, entityService.list(new QueryWrapper<ProcessTask>().eq("process_name", equipment.getType())));
    }
    //为生产线创建工序区
    @SysLog(action = "createProcessTask", value = "为生产线创建工序区")
    @ApiOperation(value = "为生产线创建工序区")
    @GetMapping("/createProcessTask")
    public Result createProcessTask(Integer lineId,String processName) {
        ProcessLine processLine = processLineService.getById(lineId);
        ProcessTask processTask = new ProcessTask();
        processTask.setLineId(lineId);
        processTask.setProcessName(processName);
        processTask.setStatus("待生产");
        processTask.setCount(0);
        processTask.setProductModel(processLine.getProductModel());
        processTask.setCreatedAt(LocalDateTime.now());
        processTask.setUpdatedAt(LocalDateTime.now());
        entityService.save(processTask);
        return new Result<>(true, processTask);
    }

    @SysLog(action = "searchAnd", value = "工序名状态复合查询")
    @ApiOperation(value = "工序名状态同时查询")
    @GetMapping("/searchAnd")
    public Result<Page<ProcessTask>> searchAnd(@RequestParam(required = false) String name,
                                               @RequestParam(required = false) String status, final Page page){
        try {
            LambdaQueryWrapper<ProcessTask> wrapper = new LambdaQueryWrapper<>();
            if (StringUtil.isNotBlank(name)) {
                wrapper.and(q ->
                        q.eq(ProcessTask::getProcessName, name)
                                .or()
                                .eq(ProcessTask::getProductModel, name)
                );
            }
            wrapper.eq(StringUtil.isNotBlank(status), ProcessTask::getStatus, status);
            Page<ProcessTask> entitys = entityService.page(page, wrapper);
            if (null != entitys) {
                return new Result<>(true, entitys);
            }
            return new Result<>(true);
        } catch (Exception e) {
            LOG.error("设备名搜索失败", e);
            return new Result<>(false, "设备名搜索失败", e.getMessage());
        }
    }
}
